import json
import re
from datetime import datetime

from django.contrib.auth import login, authenticate, logout
from django.views import View
from django.http import JsonResponse
from django_redis import get_redis_connection

from .models import User
from homes.models import House

from ihome.utils.views import LoginRequiredJSONMixin
from ihome.utils.logger import logger
from ihome.utils import statusCode


class RegisterView(View):
    """注册页面接口"""

    def post(self, request):

        data = json.loads(request.body.decode())

        mobile = data.get('mobile')
        phonecode = data.get('phonecode')
        password = data.get('password')

        if not all([mobile, phonecode, password]):
            return JsonResponse({
                'errno': statusCode.PARAMERR,
                'errmsg': '参数错误',
            })
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({
                'errno': statusCode.PARAMERR,
                'errmsg': '参数错误',
            })
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({
                'errno': statusCode.PARAMERR,
                'errmsg': '参数错误',
            })

        # TODO 业务性检验--短信验证码等
        conn = get_redis_connection('verify_code')

        # (1)读取redis中的短信验证码
        sms_code_from_redis = conn.get('sms_%s' % mobile)

        # (2)、判断是否过期
        if not sms_code_from_redis:
            return JsonResponse({
                'errno': statusCode.NODATA,
                'errmsg': '无数据'
            })

        # (3)、判断和用户输入的是否一致
        if sms_code_from_redis.decode() != phonecode:
            return JsonResponse({
                'errno': statusCode.PARAMERR,
                'errmsg': '参数错误'
            })

        try:
            user = User.objects.create_user(
                username=mobile,
                mobile=mobile,
                password=password
            )
        except Exception as e:
            logger.error('注册用户，写入mysql失败', e)
            return JsonResponse({
                'errno': statusCode.DBERR,
                'errmsg': '数据库查询错误'

            })

        login(request, user)

        response = JsonResponse({
            'errno': statusCode.OK,
            'errmsg': '注册成功'
        })

        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)

        return response


class LoginView(View):
    """登录接口 """

    def get(self, request):
        """判断是否登录接口"""

        user = request.user

        return JsonResponse({
            "errno": statusCode.OK,
            "errmsg": "已登录",
            "data": {
                "user_id": user.id,
                "name": user.username
            }})

    def delete(self, request):
        """退出登录接口"""

        # 清理 session
        logout(request)

        # 创建 response 对象.
        response = JsonResponse({'errno': statusCode.OK, 'errmsg': '已登出'})

        # 调用对象的 delete_cookie 方法, 清除cookie
        response.delete_cookie('username')

        # 返回响应
        return response

    def post(self, request):
        """登录接口"""

        data = json.loads(request.body.decode())
        mobile = data.get('mobile')
        password = data.get('password')

        if not all([mobile, password]):
            return JsonResponse({
                'errno': statusCode.PARAMERR,
                'errmsg': '参数错误'
            })
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({
                'errno': statusCode.PARAMERR,
                'errmsg': '参数错误',

            })
        if not re.match(r'^[a-zA-Z0-9_]{8,20}$', password):
            return JsonResponse({
                'errno': statusCode.PARAMERR,
                'errmsg': '参数错误',
            })

        # 业务数据处理
        user = authenticate(request, username=mobile, password=password)

        # 判断是否为空,如果为空,返回
        if user is None:
            return JsonResponse({
                'errno': statusCode.LOGINERR,
                'errmsg': '用户登录失败'
            })

        # TODO 状态保存
        login(request, user)

        # 构建响应
        response = JsonResponse({'errno': statusCode.OK, 'errmsg': '登录成功'})

        # TODO: 在cookie中设置username记录登陆用户名作前端页面展示
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)

        return response


class UserCenterrView(LoginRequiredJSONMixin, View):
    """个人中心接口"""

    def get(self, request):

        user = request.user

        try:
            img_url = user.avatar.url
        except Exception as e:
            img_url = ""

        return JsonResponse({
            "data": {
                "avatar": img_url,
                "create_time": user.date_joined,
                "mobile": user.mobile,
                "name": user.username,
                "user_id": user.id,
            },
            "errmsg": "OK",
            "errno": statusCode.OK,
        })


class UserModificationView(LoginRequiredJSONMixin, View):
    """修改用户名接口"""

    def put(self, request):
        data = json.loads(request.body.decode())
        name = data.get('name')

        if not name:
            return JsonResponse({
                "errmsg": "参数错误",
                "errno": statusCode.PARAMERR,
            })

        # TODO:判断是否重名
        count = User.objects.filter(username=name).count()
        if not count:
            return JsonResponse({
                "errmsg": "用户名不能重复",
                "errno": statusCode.DATAEXIST,
            })

        user = request.user
        try:
            user.username = name
            user.save()
        except User as e:
            logger.info('用户重命名写入失败：', e)
            return JsonResponse({
                "errmsg": "文件读写错误",
                "errno": statusCode.IOERR,
            })
        return JsonResponse({
            "errmsg": "修改成功",
            "errno": statusCode.OK,
        })


class AvatarView(LoginRequiredJSONMixin, View):
    """上传图片接口"""

    def post(self, request):
        user = request.user  # 获取用户

        image_file = request.FILES.get('avatar', None)

        if image_file is None:
            return JsonResponse({'code': statusCode.NODATA, 'errmsg': 'NODATA'},
                                json_dumps_params={'ensure_ascii': False})

        try:
            user.avatar = image_file
            user.save()
        except Exception as e:
            logger.info('上传图片失败：', e)
            return JsonResponse({
                "errmsg": "文件读写错误",
                "errno": statusCode.IOERR,
            })

        return JsonResponse({
            'data': {
                'avatar_url': user.avatar.url
            },
            'errno': statusCode.OK,
            'errmsg': "头像上传成功"
        })


class MyHomeList(LoginRequiredJSONMixin, View):
    """获取用户房屋列表接口"""

    def get(self, request):

        user = request.user

        try:
            house_all = user.houses.all()
        except Exception as e:
            logger.info('文件读写错误', e)
            return JsonResponse({'errno': statusCode.DBERR, 'errmsg': '数据库查询错误'})

        houses_list = []
        for houses in house_all:
            houses_list.append({
                'address': houses.address,
                'area_name': houses.area.name,
                'ctime': houses.create_time.date(),
                'house_id': houses.id,
                'img_url': houses.index_image_url.url,
                'order_count': houses.order_set.all().count(),
                'price': houses.price,
                'room_count': houses.room_count,
                'title': houses.title,
                'user_avatar': user.avatar.url,
                'is_active': houses.is_active
            })

        # 2 构建响应
        return JsonResponse({
            'data': {
                'houses': houses_list
            },
            'errmsg': 'ok',
            'errno': statusCode.OK
        })


class CertificationView(LoginRequiredJSONMixin, View):
    """实名认证接口"""

    def post(self, request):

        user = request.user

        user_real_info = json.loads(request.body.decode())

        real_name = user_real_info.get('real_name')
        id_card = user_real_info.get('id_card')

        if not all([real_name, id_card]):
            return JsonResponse({'code': statusCode.PARAMERR, 'errmsg': '参数错误'})

        if not re.match(r'^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,20}$', real_name):
            return JsonResponse({'code': statusCode.PARAMERR, 'errmsg': '姓名不符合要求'})

        if not re.match(r'^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$',
                        id_card):
            return JsonResponse({'code': statusCode.PARAMERR, 'errmsg': '参数错误'})

        try:
            user.real_name = real_name
            user.id_card = id_card
            user.save()
        except Exception as e:
            logger.info('实名认证数据上传失败：', e)
            return JsonResponse({
                "errmsg": "文件读写错误",
                "errno": statusCode.IOERR,
            })

        return JsonResponse({'errno': statusCode.OK, 'errmsg': '认证信息保存成功',
                             'data': {
                                 'real_name': user.real_name,
                                 'id_card': user.id_card
                             }
                             })

    def get(self, request):

        user = request.user

        return JsonResponse({'errno': statusCode.OK,
                             'errmsg': 'ok',
                             'data': {
                                 'real_name': user.real_name,
                                 'id_card': user.id_card
                             }
                             })


class UpHouseView(LoginRequiredJSONMixin, View):

    def put(self, request, house_id):

        try:
            house = House.objects.get(pk=house_id)
            house.is_active = True
            house.save()
        except Exception as e:
            logger.info('数据库查询错误：', e)
            return JsonResponse({
                "errmsg": "数据库查询错误",
                "errno": statusCode.DBERR,
            })

        return JsonResponse({'errno': statusCode.OK,
                             'errmsg': 'ok',
                             })


class DownHouseView(LoginRequiredJSONMixin, View):

    def put(self, request, house_id):

        try:
            house = House.objects.get(pk=house_id)
        except Exception as e:
            logger.info('数据库查询错误：', e)
            return JsonResponse({
                "errmsg": "数据库查询错误",
                "errno": statusCode.DBERR,
            })

        now_time = datetime.now().date()
        orders = house.order_set.all()
        for order in orders:
            st_time = order.begin_date
            en_time = order.end_date

            if (st_time > now_time) or(st_time < now_time < en_time):
                return JsonResponse({
                    "errmsg": f"该房屋已预定，暂不能下架，请在：{en_time}后处理",
                    "errno": statusCode.DBERR,
                })

        house.is_active = False
        house.save()

        return JsonResponse({'errno': statusCode.OK,
                             'errmsg': 'ok',
                             })

